package com.legrand.route.util;

import com.legrand.core.entity.User;
import io.jsonwebtoken.*;
import org.apache.commons.lang3.StringUtils;
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.openssl.PEMKeyPair;
import org.bouncycastle.openssl.PEMParser;
import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;

import java.io.IOException;
import java.io.StringReader;
import java.security.KeyPair;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Security;
import java.security.cert.CertificateException;
import java.util.Calendar;
import java.util.Date;
import java.util.UUID;

/**
*@author xiah
*2018-07-11 03:09:12
*/
public final class JWTUtils {

    public static Claims convertJWTToken2Claims(String jwtToken, String pemPubKey) throws IOException {
        JwtParser jwtParser = Jwts.parser();
        jwtParser.setSigningKey(convertPemToPublicKey(pemPubKey));
        Claims tokenBody = jwtParser.parseClaimsJws(jwtToken).getBody();
        return tokenBody;
    }

    public static String convertUser2JWTToken(User user, String pemKey) throws IOException {
        String ss = "-----BEGIN PRIVATE KEY-----\n" +
                "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAJSn+hXW9Zzz9ORB\n" +
                "KIC9Oi6wzM4zhqwHaKW2vZAqjOeLlpUW7zXwyk4tkivwsydPNaWUm+9oDlEAB2ls\n" +
                "QJv7jwWNsF7SGx5R03kenC+cf8Nbxlxwa+Tncjo6uruEsK/Vke244KiSCHP8BOuH\n" +
                "I+r5CS0x9edFLgesoYlPPFoJxTs5AgMBAAECgYBL/6iiO7hr2mjrvMgZMSSqtCaw\n" +
                "kLUcA9mjRs6ZArfwtHNymzwGZqj22ONu5WqiASPbGCO0fI09KfegFQDe/fe6wnpi\n" +
                "rBWtawLoXCZmGrwC+x/3iqbiGJMd7UB3FaZkZOzV5Jhzomc8inSJWMcR+ywiUY37\n" +
                "stfVDqR1sJ/jzZ1OdQJBAO8vCa2OVQBJbzjMvk8Sc0KiuVwnyqMYqVty6vYuufe9\n" +
                "ILJfhwhYzE82wIa9LYg7UK2bPvKyyehuFfqI5oU5lU8CQQCfG5LA3gp3D1mS7xxz\n" +
                "tqJ+cm4SPO4R6YzVybAZKqKUvTFSKNV57Kp/LL7WjtUUNr+dY+aYRlKo81Hq61y8\n" +
                "tBT3AkAjJyak+2ZCxIg0MONHe8603HWhtbdygQ1jA2DFDdkHMCS+EowmDeb5PXLO\n" +
                "Wr92ZkFVQpvdz6kdIBDa4YP/0JbBAkBVHLjqd1z9x7ZRBZwgwkg2gBwloXZxGpB+\n" +
                "JMARFl+WVYa2vqVD7bhfA56qxAl0IL1sAm7ucl/xhQgDNRiM0YCNAkEAqySTBx2H\n" +
                "O9VyzuWWbf7BYTNsxfO80GaRkZGENfqO1QgnhT1FMeK+ox7Kbi+nSaCBoPjNzyrM\n" +
                "bU08M6nSnkDEGA==\n" +
                "-----END PRIVATE KEY-----";
        PrivateKey privateKey = convertPemToPrivateKey(ss);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.add(Calendar.DATE, 7);
        JwtBuilder jwtBuilder = Jwts.builder()
                /** 签发JWT TOKEN 随机ID*/
                .setId(UUID.randomUUID().toString())
                /** 签发JWT TOKEN 主体信息*/
                .setSubject("cp58.userId" + user.getId() + "@tomaer.com")
                /** JWT TOKEN 失效时间*/
                .setExpiration(calendar.getTime())
                /** 签发人*/
                .setIssuer("https://www.tomaer.com")
                /** 签发时间*/
                .setIssuedAt(new Date())
                .claim("userId", user.getId());
        if (StringUtils.isNotBlank(user.getTelephone())) {
            jwtBuilder.claim("telephone", user.getTelephone());
        }
        if (StringUtils.isNotBlank(user.getUserName())) {
            jwtBuilder.claim("userName", user.getUserName());
        }
        /**用户角色*/
       /* List<String> roles = user.getUserRoles();
        if (null != roles) {
            jwtBuilder.claim("https://cp58.com/roles", roles);
        }*/
        return jwtBuilder.signWith(SignatureAlgorithm.RS256, privateKey).compact();
    }


    @SuppressWarnings("resource")
    private static PublicKey convertPemToPublicKey(String pem) throws IOException {
        Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
        PEMParser pemParser = new PEMParser(new StringReader(pem));
        Object keyObj = pemParser.readObject();
        JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider("BC");
        PublicKey actualPublicKey = converter.getPublicKey((SubjectPublicKeyInfo) keyObj);
        return actualPublicKey;
    }

    @SuppressWarnings("resource")
    private static PrivateKey convertPemToPrivateKey(String pem) throws IOException {
        Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
        PEMParser pemParser = new PEMParser(new StringReader(pem));
        Object keyObj = pemParser.readObject();
        JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider("BC");
        PrivateKey actualPrivateKey = converter.getPrivateKey((PrivateKeyInfo) keyObj);
        return actualPrivateKey;
    }

    @SuppressWarnings({"resource", "unused"})
    private static KeyPair convertPemToKeyPair(String pem) throws IOException, CertificateException {
        Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
        PEMParser pemParser = new PEMParser(new StringReader(pem));
        Object keyObj = pemParser.readObject();
        JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider("BC");
        KeyPair actualKeyPair = converter.getKeyPair((PEMKeyPair) keyObj);
        return actualKeyPair;
    }
}
